package com.liyiruo.html2pdf.controller;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.io.source.ByteArrayOutputStream;
import com.itextpdf.layout.font.FontProvider;
import com.liyiruo.html2pdf.entiry.Receipt;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.thymeleaf.ITemplateEngine;
import org.thymeleaf.context.Context;

import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@Controller
@RequestMapping("/html2pdf")
public class Html2PdfController {
    private final ITemplateEngine templateEngine ;
    public Html2PdfController(ITemplateEngine templateEngine) {
        this.templateEngine = templateEngine;
    }
    @RequestMapping("/receipt")
    public ModelAndView getTemplate() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject(getData());
        modelAndView.setViewName("receipt");
        return modelAndView;
    }
    @ResponseBody
    @GetMapping("/download")
    public ResponseEntity<byte[]> downloadEJournalFile(HttpServletRequest request,
                                                       HttpServletResponse response) throws Exception {
        // 1.准备数据
        Map<String, Object> variables = Map.of("receipt", getData()) ;
        // 2.创建上下文并添加变量(模板需要的数据)
        Context context = new Context();
        context.setVariables(variables);
        // 2.1.获取解析后的模板内容
        String receiptTemplate = templateEngine.process("receipt", context);
        // 3.配置模板中使用的基础资源信息
        ConverterProperties converterProperties = new ConverterProperties();
        // 如果你的模板中引用了样式，那么你需要设置
        converterProperties.setBaseUri("http://localhost:8080") ;
        // 3.1.设置字体
        FontProvider fontProvider = new FontProvider();
        // 加载系统所有字体（最简单方式）
        fontProvider.addSystemFonts() ;
        converterProperties.setFontProvider(fontProvider) ;
        // 3.2.HTML到PDF转换
        ByteArrayOutputStream target = new ByteArrayOutputStream();
        HtmlConverter.convertToPdf(receiptTemplate, target, converterProperties);
        // 4.设置下载信息
        String fileName = URLEncoder.encode("收据明细.pdf", StandardCharsets.UTF_8);
        HttpHeaders header = new HttpHeaders();
        header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
        header.add("Cache-Control", "no-cache, no-store, must-revalidate") ;
        header.add("Pragma", "no-cache") ;
        header.add("Expires", "0") ;
        return ResponseEntity.ok()
                .headers(header)
                .contentType(MediaType.APPLICATION_PDF)
                .body(target.toByteArray()) ;
    }
    public Receipt getData() {
        Receipt receipt = new Receipt();
        receipt.setScope("中国");

        // 商户信息
        receipt.setMerchantName("示例商户");
        receipt.setMerchantId("M123456789");
        receipt.setTerminalId("T987654321");
        receipt.setMerchantCity("北京市");

        // 交易基本信息
        receipt.setStan("123456");
        receipt.setTransactionDate("20251014");
        receipt.setTransactionType("消费");
        receipt.setRequestAmount(new BigDecimal("199.99"));

        // 交易详情
        receipt.setMcc("5411");
        receipt.setScheme("银联");
        receipt.setMaskedPan("6222****1234");
        receipt.setAcquirer("985400");

        // 系统信息
        receipt.setApprovalNumber("A654321");
        receipt.setProcessingCode("000000");
        receipt.setResponseCode("00");
        receipt.setRetrievalNumber("123456789012");
        receipt.setDisplayMessage("交易成功");

        return receipt;
    }
}
